package com.splic.framework.jwt.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.splic.common.core.domain.AjaxResult;
import com.splic.common.utils.security.AESUtils;
import com.splic.framework.shiro.service.SysDeviceService;
import com.splic.product.dto.DeviceDto;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * ==========================
 * 开发：yuxiangjie
 * 创建时间：2022-03-21 16:02
 * 版本: 1.0
 * 描述：TODO
 * ==========================
 */
public class GlobalParamsFilter extends AccessControlFilter {

    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalParamsFilter.class);
    private final ThreadLocal<String> MSG_HOLDER = new ThreadLocal<>();

    private SysDeviceService deviceService;

    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
        return this.checkGlobalParams(servletRequest,servletResponse);
    }

    /**
     * 校验全局参数
     */
    protected boolean checkGlobalParams(ServletRequest request, ServletResponse response) throws Exception
    {
        String params = WebUtils.toHttp(request).getHeader("globalParams");
        if (StringUtils.isEmpty(params))
        {
            MSG_HOLDER.set("消息头全局参数不正确，header需要携带globalParams参数");
            return false;
        }
        String encrypted = WebUtils.toHttp(request).getHeader("encrypted");
        if (!StringUtils.isEmpty(encrypted) && "true".equals(encrypted)) {
            try {
                params = AESUtils.decrypt(params, "pRvxtOnSZepDn1kTNXdxIw==");
            } catch (Exception e) {
                LOGGER.error("checkGlobalParams解密失败：{}", params, e);
                MSG_HOLDER.set("消息头全局参数不正确，header携带globalParams参数解密失败");
                return false;
            }
        }
        try
        {
            DeviceDto deviceDto = JSONObject.parseObject(params,DeviceDto.class);
            if(deviceDto == null){
                MSG_HOLDER.set("消息头全局参数不正确，header需要携带global_params参数");
                return false;
            }
            if (StringUtils.isEmpty(deviceDto.getDeviceIdentify())){
                String deviceIdentify = deviceService.interfaceNeedInfo(deviceDto);
                deviceDto.setDeviceIdentify(deviceIdentify);
            }
            return true;
        }
        catch (Exception e)
        {
            MSG_HOLDER.set("消息头全局参数不正确：" + e.getMessage());
            return false;
        }
    }

    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        this.jwtFail(servletRequest, servletResponse, 401, "对不起,您无权限进行操作!");
        return false;
    }

    /**
     * 认证失败，异常返回
     */
    protected void jwtFail(ServletRequest request, ServletResponse response, int code, String message)
    {
        HttpServletResponse httpResponse = WebUtils.toHttp(response);
        String contentType = "application/json;charset=UTF-8";
        httpResponse.setStatus(401);
        httpResponse.setContentType(contentType);
        try
        {
            String msg = StringUtils.isNotEmpty(MSG_HOLDER.get()) ? MSG_HOLDER.get() : message;
            AjaxResult ajaxResult = new AjaxResult().put(AjaxResult.CODE_TAG, code).put(AjaxResult.MSG_TAG, msg);
            PrintWriter printWriter = httpResponse.getWriter();
            printWriter.append(JSON.toJSONString(ajaxResult));
        }
        catch (IOException e)
        {
            //LOGGER.error("sendChallenge error,can not resolve httpServletResponse");
        }
    }

    public void setGlobalParamsDeviceService(SysDeviceService sysDeviceService)
    {
        this.deviceService = sysDeviceService;
    }
}
